class Circle {
  float x, y, r;

  Circle(PVector v1, PVector v2) {
    PVector c = PVector.mult(PVector.add(v1, v2), 0.5);
    this.x = c.x;
    this.y = c.y;
    this.r = v1.dist(v2) * 0.5;
  }

  Circle(PVector v1, PVector v2, PVector v3) {
    PMatrix3D m = new PMatrix3D(2 * v1.x, 2 * v1.y, 1.0, 0, 
    2 * v2.x, 2 * v2.y, 1.0, 0, 
    2 * v3.x, 2 * v3.y, 1.0, 0, 
    0, 0, 0, 1);
    if (!m.invert()) {
      throw new Error("points collinear");
    }
    float[] c = m.mult(new float[] {
      -v1.dot(v1), -v2.dot(v2), -v3.dot(v3)
    }
    , null);
    this.x = -c[0];
    this.y = -c[1];
    this.r = sqrt(c[0] * c[0] + c[1] * c[1] - c[2]);
  }

  boolean contains(PVector v) {
    float dx = this.x - v.x;
    float dy = this.y - v.y;
    return dx * dx + dy * dy <= this.r * this.r;
  }
  
  void translate(PVector t) {
    this.x += t.x;
    this.y += t.y;
  }

  void draw() {
    pushStyle();
    stroke(0, 0, 255);
    noFill();
    float d = this.r * 2;
    ellipse(this.x, this.y, d, d);
    line(this.x - 10, this.y - 10, this.x + 10, this.y + 10);
    line(this.x - 10, this.y + 10, this.x + 10, this.y - 10);
    popStyle();
  }
}

